/**
 * 拖拽指令
 * @author luguoxiang
 * @date 2021-09-07
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
import { addEventListener, removeEventListener } from '@/soar';

function dispatchResize() {
  const event = document.createEvent('HTMLEvents');
  event.initEvent('resize', true, true);
  // @ts-ignore
  event.eventType = 'message';
  window.dispatchEvent(event);
}

/**
 * 元素拖拽
 * @param el 元素
 * @param config
 */
function drag(el: any, config: any) {
  const selector = typeof config.value === 'string' ? [config.value] : config.value ?? [];
  let id = null;
  if (selector[0]) {
    if (!el.id) {
      el.id = `drag-${String(Math.random()).substring(2)}`;
    }
    id = el.id;
    el = document.querySelector(`#${id} ${selector[0]}`);
  }
  if (!el) {
    return;
  }
  // 添加拖拽元素
  el.dragData = {};
  if (config.arg === false || config.arg === 'false') {
    el.removeChild(el.dragData.top);
    el.removeChild(el.dragData.right);
    el.removeChild(el.dragData.bottom);
    el.removeChild(el.dragData.left);
    el.removeChild(el.dragData.br);
    return;
  }
  // 固定宽高度
  // el.style.height = el.clientHeight + 'px'
  el.style.width = `${el.clientWidth}px`;
  el.style.position = 'absolute';
  // 注册拖动事件
  addEventListener(el, 'dragstart', function (e: any) {
    el.dragData.disX = e.clientX - el.offsetLeft;
    el.dragData.disY = e.clientY - el.offsetTop;
  });
  addEventListener(el, 'dragend', function (e: any) {
    let left = e.clientX - el.dragData.disX;
    let top = e.clientY - el.dragData.disY;
    if (left > window.innerWidth - el.offsetWidth) {
      left = window.innerWidth - el.offsetWidth;
    }
    if (top > window.innerHeight - el.offsetHeight) {
      top = window.innerHeight - el.offsetHeight;
    }
    el.style.left = `${left < 0 ? 0 : left}px`;
    el.style.top = `${top < 0 ? 0 : top}px`;
    el.draggable = false;
  });

  // 开启拖拽
  function openDrag() {
    el.draggable = true;
  }

  function addTrigger(trigger: any) {
    if (trigger) {
      addEventListener(trigger, 'mousedown', openDrag);
      trigger.classList.add('lg-drag-trigger');
    }
  }

  // 注册四边拖拽触发元素
  function appendMove() {
    const trigger = document.createElement('div');
    addTrigger(trigger);
    el.append(trigger);
    return trigger;
  }
  const top = appendMove();
  top.classList.add('lg-drag-top');
  el.dragData.top = top;
  const bottom = appendMove();
  bottom.classList.add('lg-drag-bottom');
  el.dragData.bottom = bottom;
  const left = appendMove();
  left.classList.add('lg-drag-left');
  el.dragData.left = left;
  const right = appendMove();
  right.classList.add('lg-drag-right');
  el.dragData.right = right;

  // 注册其他拖拽触发元素
  for (let i = 1; i < selector.length; i++) {
    addTrigger(document.querySelector(`#${id} ${selector[i]}`));
  }
  // 是否支持改变款高度
  if (!config.modifiers.resize) {
    return;
  }
  function appendResize(mousemove: any) {
    const div: HTMLDivElement = document.createElement('div');
    addEventListener(div, 'mousedown', function (e: MouseEvent) {
      el.dragData.disX = e.clientX;
      el.dragData.disY = e.clientY;
      el.dragData.width = el.clientWidth;
      el.dragData.height = el.clientHeight;
      addEventListener(document, 'mousemove', mousemove);
    });
    addEventListener(document, 'mouseup', function (e: MouseEvent) {
      removeEventListener(document, 'mousemove', mousemove);
      el.dragData.disX = e.clientX;
      el.dragData.disY = e.clientY;
      el.dragData.width = el.clientWidth;
      el.dragData.height = el.clientHeight;
      dispatchResize();
    });
    el.append(div);
    return div;
  }
  // 添加四个角的控件
  const br = appendResize((e: MouseEvent) => {
    el.style.width = `${el.dragData.width + (e.clientX - el.dragData.disX)}px`;
    el.style.height = `${el.dragData.height + (e.clientY - el.dragData.disY)}px`;
  });
  br.classList.add('lg-resize-br');
  el.dragData.br = br;
}

/**
 * 调整元素大小
 * @param el 元素
 * @param config 配置
 */
function resize(el: any, config: any) {
  if (config.value) {
    if (!el.id) {
      el.id = `drag-${String(Math.random()).substring(2)}`;
    }
    el = document.querySelector(`#${el.id} ${config.value}`);
  }
  el.dragData = {};
  if (config.arg === false || config.arg === 'false') {
    el.removeChild(el.dragData.br);
    return;
  }
  // 固定宽高度
  el.style.width = `${el.clientWidth}px`;
  el.style.position = 'absolute';

  // 是否支持改变款高度
  function appendResize(mousemove: any) {
    const div = document.createElement('div');
    addEventListener(div, 'mousedown', function (e: MouseEvent) {
      el.dragData.disX = e.clientX;
      el.dragData.disY = e.clientY;
      el.dragData.width = el.clientWidth;
      el.dragData.height = el.clientHeight;
      addEventListener(document, 'mousemove', mousemove);
    });
    addEventListener(document, 'mouseup', function (e: MouseEvent) {
      removeEventListener(document, 'mousemove', mousemove);
      el.dragData.disX = e.clientX;
      el.dragData.disY = e.clientY;
      el.dragData.width = el.clientWidth;
      el.dragData.height = el.clientHeight;
      dispatchResize();
    });
    el.append(div);
    return div;
  }
  // 添加四个角的控件
  const br = appendResize((e: any) => {
    el.style.width = `${el.dragData.width + (e.clientX - el.dragData.disX)}px`;
    el.style.height = `${el.dragData.height + (e.clientY - el.dragData.disY)}px`;
  });
  br.classList.add('lg-resize-br');
  el.dragData.br = br;
}

export default {
  drag: {
    mounted(el: Element, elementObj: any) {
      setTimeout(() => drag(el, elementObj), 500);
    },
  },
  resize: {
    mounted(el: Element, elementObj: any) {
      setTimeout(() => resize(el, elementObj), 500);
    },
  },
};
